package com.mmall.controller.interceptor;

import com.mmall.common.Const;
import com.mmall.common.ServerResponse;
import com.mmall.pojo.User;
import com.mmall.utils.CookieUtil;
import com.mmall.utils.JsonUtil;
import com.mmall.utils.RedisPoolUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

@Slf4j
public class AuthorityInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
                             Object handler) throws Exception {
        log.info("AuthorityInterceptor preHandle...");
        HandlerMethod handlerMethod = (HandlerMethod) handler;
        String methodName = handlerMethod.getMethod().getName();
        String className = handlerMethod.getBean().getClass().getSimpleName();

        StringBuffer requestParamBuffer = new StringBuffer();
        Map paramMap = request.getParameterMap();
        Iterator it = paramMap.entrySet().iterator();
        while (it.hasNext()){
            Map.Entry entry = (Map.Entry)it.next();
            String mapKey = (String)entry.getKey();

            String mapValue = StringUtils.EMPTY;
            //request这个参数的map，里面的value返回的是一个String[]
            Object obj = entry.getValue();
            if(obj instanceof String[]){
                String[] strs = (String[])obj;
                mapValue = Arrays.toString(strs);
            }
            requestParamBuffer.append(mapKey).append("=").append(mapValue);
        }
        //第二种放过登陆拦截的方式，第一种在配置文件中配置/manage/user/login.do
        if (StringUtils.equals(className, "UserManagerController")
                && StringUtils.equals(methodName, "login")) {
            log.info("权限拦截器拦截到请求,className:{},methodName:{}",className,methodName);
            //如果是拦截到登录请求，不打印参数，因为参数里面有密码，全部会打印到日志中，防止日志泄露
            return true;
        }
        log.info("权限拦截器拦截到请求,param:{}",requestParamBuffer.toString());

        User user = null;
        String loginToken = CookieUtil.readLoginToken(request);
        if (StringUtils.isNotEmpty(loginToken)) {
            String userJsonStr = RedisPoolUtil.get(loginToken);
            user = JsonUtil.stringToObj(userJsonStr, User.class);
        }
        //如果用户不存在或者不是管理员
        if (user == null || (user.getRole().intValue() != Const.Role.ROLE_ADMIN)) {
            //返回false不会调用controller里面的方法
            response.reset();//这里要添加reset，否则回报异常getWriter() has already been called for this response.，
            response.setCharacterEncoding("UTF-8");//设置编码，否则回乱码
            response.setContentType("application/json;charset=UTF-8");//设置返回类型为json

            PrintWriter out = response.getWriter();
            if (user == null) {
                //富文本上传返回特殊格式
                if (StringUtils.equals(className, "ProductManageController")
                        && StringUtils.equals(methodName, "richTextImgUpload")) {
                    Map resultMap = new HashMap();
                    resultMap.put("success", false);
                    resultMap.put("msg", "拦截器拦截,用户未登录");
                    out.print(JsonUtil.objToString(resultMap));
                } else {
                    out.print(JsonUtil.objToString(ServerResponse.retErrorMsg("拦截器拦截,用户未登录")));
                }
            } else {
                //富文本上传返回特殊格式
                if (StringUtils.equals(className, "ProductManageController")
                        && StringUtils.equals(methodName, "richTextImgUpload")) {
                    Map resultMap = new HashMap();
                    resultMap.put("success", false);
                    resultMap.put("msg", "拦截器拦截,用户无权限");
                    out.print(JsonUtil.objToString(resultMap));
                } else {
                    out.print(JsonUtil.objToString(ServerResponse.retErrorMsg("拦截器拦截,用户无权限")));
                }
            }
            out.flush();
            out.close();//关闭资源

            return false;
        }

        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        log.info("AuthorityInterceptor postHandle...");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        log.info("AuthorityInterceptor afterCompletion...");
    }
}
